Passed
Push — master ( d53e61...cdfcfd )
by Swen
01:12 queued 12s
created

ast.js ➔ ???   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 1
c 4
b 0
f 0
nc 1
nop 3
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
1 1
const fs = require('fs');
2
3 1
const Babylon = require('babylon');
4
5 1
const Resolver = require('./resolver');
0 ignored issues
show
Unused Code introduced by
The constant Resolver seems to be never used. Consider removing it.
Loading history...
6 1
const extractExportSpecifiers = require('./extractExportSpecifiers');
7 1
const extractImportSpecifiers = require('./extractImportSpecifiers');
8
9
/**
10
 * Small wrapper over the Babylon ES6 AST.
11
 */
12
class AST {
13
    /**
14
     * Initializes a new instance of {@see AST}.
15
     * @param ast The AST to wrap.
16
     * @param resolver The resolver to use when resolving a file.
17
     * @param source The path to the file from which this AST was parsed.
0 ignored issues
show
Documentation Bug introduced by
The parameter source does not exist. Did you maybe mean sourcePath instead?
Loading history...
18
     */
19
    constructor(ast, resolver, sourcePath) {
20 19
        this.ast = ast;
21 19
        this.resolver = resolver;
22 19
        this.sourcePath = sourcePath;
23
    }
24
25
    /**
26
     * Parses the specified JS/ES6 file with the Babylon parser
27
     * and returns the AST.
28
     * @param filePath The path to the file to parse.
29
     * @param resolver The resolver to use to resolve the specified file.
30
     * @returns The AST of the specified file or null if the specified
31
     * file could not be found or could not be parsed.
32
     */
33
    static parseFrom(filePath, resolver) {
34 19
        try {
35 19
            const ast = Babylon.parse(fs.readFileSync(filePath, 'utf-8'), {
36
                sourceType: 'module',
37
                plugins: [
38
                    'jsx',
39
                    'flow',
40
                    'estree',
41
                    'typescript',
42
                    'doExpressions',
43
                    'objectRestSpread',
44
                    'decorators',
45
                    'decorators2',
46
                    'classProperties',
47
                    'classPrivateProperties',
48
                    'classPrivateMethods',
49
                    'exportExtensions',
50
                    'asyncGenerators',
51
                    'functionBind',
52
                    'functionSent',
53
                    'dynamicImport',
54
                    'numericSeparator',
55
                    'optionalChaining',
56
                    'importMeta',
57
                    'bigInt',
58
                    'optionalCatchBinding',
59
                    'throwExpressions',
60
                    'pipelineOperator',
61
                    'nullishCoalescingOperator',
62
                ],
63
            });
64
65 19
            return new AST(ast, resolver, filePath);
66
        } catch (error) {
67
            return null;
68
        }
69
    }
70
71
    /**
72
     * Resolves the absolute path to the specified file,
73
     * relative to the file being parsed.
74
     * @param path The path to resolve.
75
     * @returns The absolute path to the specified file or
76
     * null if the path could not be resolved.
77
     */
78
    resolve(path) {
79 69
        return this.resolver.resolveFile(path, this.sourcePath);
80
    }
81
82
    /**
83
     * Gets a flat list of all the import specifiers in this file.
84
     */
85
    importSpecifiers() {
86 51
        const declarations = this.ast.program.body
87 166
            .filter(node => node.type === 'ImportDeclaration');
88
89 51
        return extractImportSpecifiers(declarations, this.resolve.bind(this));
90
    }
91
92
    /**
93
     * Gets a flat list of all the export specifiers in this file.
94
     */
95
    exportSpecifiers() {
96 34
        const declarations = this.ast.program.body
97 108
            .filter(node => node.type === 'ExportDefaultDeclaration' || node.type === 'ExportNamedDeclaration');
98
99 34
        return extractExportSpecifiers(declarations, this.resolve.bind(this));
100
    }
101
}
102
103
module.exports = AST;
104